home *** CD-ROM | disk | FTP | other *** search
/ Linux Cubed Series 3: Developer Tools / Linux Cubed Series 3 - Developer Tools.iso / devel / lang / lisp / stk-3.0 / stk-3 / blt-for-STk-3.0 / blt-1.9 / src / bltCutbuffer.c < prev    next >
Encoding:
C/C++ Source or Header  |  1995-07-01  |  6.7 KB  |  263 lines

  1. /*
  2.  * bltCutbuffer.c --
  3.  *
  4.  * Copyright 1993-1994 by AT&T Bell Laboratories.
  5.  * Permission to use, copy, modify, and distribute this software
  6.  * and its documentation for any purpose and without fee is hereby
  7.  * granted, provided that the above copyright notice appear in all
  8.  * copies and that both that the copyright notice and warranty
  9.  * disclaimer appear in supporting documentation, and that the
  10.  * names of AT&T Bell Laboratories any of their entities not be used
  11.  * in advertising or publicity pertaining to distribution of the
  12.  * software without specific, written prior permission.
  13.  *
  14.  * AT&T disclaims all warranties with regard to this software, including
  15.  * all implied warranties of merchantability and fitness.  In no event
  16.  * shall AT&T be liable for any special, indirect or consequential
  17.  * damages or any damages whatsoever resulting from loss of use, data
  18.  * or profits, whether in an action of contract, negligence or other
  19.  * tortuous action, arising out of or in connection with the use or
  20.  * performance of this software.
  21.  *
  22.  */
  23. #include "blt.h"
  24. #include <X11/Xproto.h>
  25.  
  26. #ifndef CUTBUFFER_VERSION
  27. #define CUTBUFFER_VERSION "1.0"
  28. #endif
  29.  
  30. /* ARGSUSED */
  31. static int
  32. RotateErrorProc(clientData, errEventPtr)
  33.     ClientData clientData;
  34.     XErrorEvent *errEventPtr;
  35. {
  36.     int *errorPtr = (int *)clientData;
  37.  
  38.     *errorPtr = TCL_ERROR;
  39.     return 0;
  40. }
  41.  
  42. static int
  43. GetCutNumber(interp, string, bufferPtr)
  44.     Tcl_Interp *interp;
  45.     char *string;
  46.     int *bufferPtr;
  47. {
  48.     int number;
  49.  
  50.     if (Tcl_GetInt(interp, string, &number) != TCL_OK) {
  51.     return TCL_ERROR;
  52.     }
  53.     if ((number < 0) || (number > 7)) {
  54.     Tcl_AppendResult(interp, "bad buffer number \"", string, "\"",
  55.         (char *)NULL);
  56.     return TCL_ERROR;
  57.     }
  58.     *bufferPtr = number;
  59.     return TCL_OK;
  60. }
  61.  
  62. static char *
  63. GetCutBuffer(tkwin, buffer)
  64.     Tk_Window tkwin;
  65.     int buffer;
  66. {
  67.     char *dataPtr;
  68.     int numBytes;
  69.     int limit;
  70.     register char *p;
  71.     register int i;
  72.     int c;
  73.  
  74.     dataPtr = XFetchBuffer(Tk_Display(tkwin), &numBytes, buffer);
  75.     if (dataPtr == NULL) {
  76.     return NULL;
  77.     }
  78.     if (dataPtr[numBytes - 1] == '\0') {
  79.     limit = numBytes - 1;
  80.     } else {
  81.     limit = numBytes;
  82.     }
  83.     for (p = dataPtr, i = 0; i < limit; i++, p++) {
  84.     c = (unsigned char)*p;
  85.     if (c == 0) {
  86.         *p = '@';        /* Convert embedded NUL bytes */
  87.     }
  88.     }
  89.     if (limit == numBytes) {
  90.     char *newPtr;
  91.  
  92.     newPtr = (char *)malloc(numBytes + 1);
  93.     if (newPtr == NULL) {
  94.         return NULL;
  95.     }
  96.     memcpy(newPtr, dataPtr, numBytes);
  97.     newPtr[numBytes] = '\0';
  98.     free(dataPtr);
  99.     dataPtr = newPtr;
  100.     }
  101.     return (dataPtr);
  102. }
  103.  
  104. static int
  105. RotateCutBuffer(tkwin, buffer)
  106.     Tk_Window tkwin;
  107.     int buffer;
  108. {
  109.     int error = TCL_OK;
  110.     Tk_ErrorHandler handler;
  111.  
  112.     handler = Tk_CreateErrorHandler(Tk_Display(tkwin), BadMatch,
  113.     X_RotateProperties, -1, RotateErrorProc, (ClientData)&error);
  114.     XRotateBuffers(Tk_Display(tkwin), buffer);
  115.     Tk_DeleteErrorHandler(handler);
  116.     XSync(Tk_Display(tkwin), False);
  117.     return (error);
  118. }
  119.  
  120. /*
  121.  *----------------------------------------------------------------------
  122.  *
  123.  * CutBufferCmd --
  124.  *
  125.  *    This procedure is invoked to process the "cutbuffer" Tcl
  126.  *    command. See the user documentation for details on what it does.
  127.  *
  128.  * Results:
  129.  *    A standard Tcl result.
  130.  *
  131.  * Side effects:
  132.  *    None.
  133.  *
  134.  *----------------------------------------------------------------------
  135.  */
  136. /* ARGSUSED */
  137. static int
  138. CutbufferCmd(clientData, interp, argc, argv)
  139.     ClientData clientData;    /* Main window associated with
  140.                  * interpreter.*/
  141.     Tcl_Interp *interp;        /* Current interpreter. */
  142.     int argc;            /* Number of arguments. */
  143.     char **argv;        /* Argument strings. */
  144. {
  145.     Tk_Window tkwin = (Tk_Window)clientData;
  146.     int buffer;            /* cut buffer number (0-7) */
  147.     char c;
  148.     int length;
  149.  
  150.     if (argc < 2) {
  151.     Tcl_AppendResult(interp, "wrong # args: should be \"",
  152.         argv[0], " option ?args?\"", (char *)NULL);
  153.     return TCL_ERROR;
  154.     }
  155.     c = argv[1][0];
  156.     length = strlen(argv[1]);
  157.     if ((c == 'g') && (strncmp(argv[1], "get", length) == 0)) {
  158.     char *string;
  159.  
  160.     if (argc > 3) {
  161.         Tcl_AppendResult(interp, "wrong # args: should be \"",
  162.         argv[0], " get ?buffer?\"", (char *)NULL);
  163.         return TCL_ERROR;
  164.     }
  165.     buffer = 0;
  166.     if (argc == 3) {
  167.         if (GetCutNumber(interp, argv[2], &buffer) != TCL_OK) {
  168.         return TCL_ERROR;
  169.         }
  170.     }
  171.     string = GetCutBuffer(tkwin, buffer);
  172.     if (string != NULL) {
  173.         Tcl_SetResult(interp, string, TCL_DYNAMIC);
  174.     }
  175.     return TCL_OK;
  176.  
  177.     } else if ((c == 'r') && (strncmp(argv[1], "rotate", length) == 0)) {
  178.     int count;
  179.  
  180.     if ((argc < 2) || (argc > 3)) {
  181.         Tcl_AppendResult(interp, "wrong # args: should be \"",
  182.         argv[0], " rotate ?buffer?\"", (char *)NULL);
  183.         return TCL_ERROR;
  184.     }
  185.     count = 1;        /* Default: rotate one position */
  186.     if (argc == 3) {
  187.         if (Tcl_GetInt(interp, argv[2], &count) != TCL_OK) {
  188.         return TCL_ERROR;
  189.         }
  190.         if ((count < 0) || (count > 8)) {
  191.         Tcl_AppendResult(interp, "bad rotate count \"", argv[2], "\"",
  192.             (char *)NULL);
  193.         return TCL_ERROR;
  194.         }
  195.     }
  196.     if (RotateCutBuffer(tkwin, count) != TCL_OK) {
  197.         Tcl_AppendResult(interp, "\"", argv[0], " ", argv[1],
  198.         "\": all cut buffers not set", (char *)NULL);
  199.         return TCL_ERROR;
  200.     }
  201.     return TCL_OK;
  202.     } else if ((c == 's') && (strncmp(argv[1], "set", length) == 0)) {
  203.     if ((argc < 2) || (argc > 4)) {
  204.         Tcl_AppendResult(interp, "wrong # args: should be \"",
  205.         argv[0], " set value ?buffer?\"", (char *)NULL);
  206.         return TCL_ERROR;
  207.     }
  208.     buffer = 0;
  209.     if (argc == 4) {
  210.         if (GetCutNumber(interp, argv[3], &buffer) != TCL_OK) {
  211.         return TCL_ERROR;
  212.         }
  213.     }
  214.     XStoreBuffer(Tk_Display(tkwin), argv[2], strlen(argv[2]) + 1, buffer);
  215.     return TCL_OK;
  216.     } else {
  217.     Tcl_AppendResult(interp, "bad option \"", argv[1],
  218.         "\": should be get, rotate, or set", (char *)NULL);
  219.     return TCL_ERROR;
  220.     }
  221. }
  222.  
  223. /*
  224.  *----------------------------------------------------------------------
  225.  *
  226.  * Blt_CutbufferInit --
  227.  *
  228.  *    This procedure is invoked to initialize the "cutbuffer" Tcl
  229.  *    command. See the user documentation for details on what it does.
  230.  *
  231.  * Results:
  232.  *    A standard Tcl result.
  233.  *
  234.  * Side effects:
  235.  *    None.
  236.  *
  237.  *----------------------------------------------------------------------
  238.  */
  239.  
  240. int
  241. Blt_CutbufferInit(interp)
  242.     Tcl_Interp *interp;
  243. {
  244.     Tk_Window tkwin;
  245.  
  246.     if (Blt_FindCmd(interp, "blt_cutbuffer", (ClientData *)NULL) == TCL_OK) {
  247.     Tcl_AppendResult(interp, "\"blt_cutbuffer\" command already exists",
  248.         (char *)NULL);
  249.     return TCL_ERROR;
  250.     }
  251.     tkwin = Tk_MainWindow(interp);
  252.     if (tkwin == NULL) {
  253.     Tcl_AppendResult(interp, "\"blt_cutbuffer\" requires Tk",
  254.         (char *)NULL);
  255.     return TCL_ERROR;
  256.     }
  257.     Tcl_SetVar2(interp, "blt_versions", "blt_cutbuffer", CUTBUFFER_VERSION,
  258.     TCL_GLOBAL_ONLY);
  259.     Tcl_CreateCommand(interp, "blt_cutbuffer", CutbufferCmd, (ClientData)tkwin,
  260.     (Tcl_CmdDeleteProc *)NULL);
  261.     return TCL_OK;
  262. }
  263.